//
//Copyright GX. Yuan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @file net.go
 * @brief Leetcode 剑指Offer 第二版
 * @details 剑指 Offer 12. 矩阵中的路径
 * @author GX. Yuan  any question please send mail to yuanguanxu@qq.com
 * @date 2021-6-28
 * @version V1.0
 * @attention 硬件平台: windows 10 家庭版
 * SDK版本：Go 1.16.5
 * IDE版本：GoLand 2020.2.3
 */
package main

import "fmt"

func exist(board [][]byte, word string) bool {
	for i,_:= range board {
		for j,_:= range board[0] {
			if dfs(board,word,i,j,0) { // 只有找到后
				return true
			}
		}
	}
	return false
}
func dfs(board [][]byte, word string, i int, j int, k int) bool {
	width := len(board)
	height := len(board[0])
	fmt.Println("高:", height, ";宽", width)
	// 对不满足条件的分支进行剪枝操作
	if i<0 || i >=len(board) ||  j< 0 || j >=len(board[0]) || board[i][j] != word[k]{
			return false
	}
	// 上面的排除的失败，如果符合，判断是否
	if k==len(word)-1{
		return  true
	}
	// 如何将空字符串赋值给byte
	board[i][j] = '\000' // 赋值特殊字符
	// 接着查找下面的字符串
	// 里面的值，找到返回true，否则返回false
	res:= dfs(board,word,i-1,j,k+1)|| dfs(board,word,i+1,j,k+1)|| dfs(board,word,i,j-1,k+1)||dfs(board,word,i,j+1,k+1)
	// 无论找没有找到，将原来的值位置值给复原
	board[i][j]=word[k]
	return res
}

func main() {

}

// 处理问题的思路是：
// 这个问题可以使用递归来解决;
// 标记方向；1234 表示上下左右查找
// 标记过的空格不可以在在此使用了;
// 查找的字符不断的衍生;
// =====================================
// 给出的函数明显不可以使用 递归来解决问题；
// 递归解决问题的方式；
// 由于返回值的关系，解决问题的方式，不能使用递归来解决问题；
// 必须找到返回值，将递归函数进行串联来解决问题。
// 官方解法：深度优先搜索解决方式
// 对应的是广度优先搜索，实现搜索方式,解决问题的处理方式。
/*
	本问题是典型的矩阵搜索问题，可使用 深度优先搜索（DFS）+ 剪枝 解决。
	深度优先搜索： 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归，先朝一个方向搜到底，再回溯至上个节点，沿另一个方向搜索，以此类推。
	剪枝： 在搜索中，遇到 这条路不可能和目标字符串匹配成功 的情况（例如：此矩阵元素和目标字符不同、此元素已被访问），则应立即返回，称之为 可行性剪枝 。
	递归参数： 当前元素在矩阵 board 中的行列索引 i 和 j ，当前目标字符在 word 中的索引 k 。
	终止条件：
	返回 falsefalse ： (1) 行或列索引越界 或 (2) 当前矩阵元素与目标字符不同 或 (3) 当前矩阵元素已访问过 （ (3) 可合并至 (2) ） 。
	返回 truetrue ： k = len(word) - 1 ，即字符串 word 已全部匹配。
	递推工作：
	标记当前矩阵元素： 将 board[i][j] 修改为 空字符 '' ，代表此元素已访问过，防止之后搜索时重复访问。
	搜索下一单元格： 朝当前元素的 上、下、左、右 四个方向开启下层递归，使用 或 连接 （代表只需找到一条可行路径就直接返回，不再做后续 DFS ），并记录结果至 res 。
	还原当前矩阵元素： 将 board[i][j] 元素还原至初始值，即 word[k] 。
	返回值： 返回布尔量 res ，代表是否搜索到目标字符串。
*/
// 深度优先搜索，本质也是对于递归的处理问题的处理方式；
// 参考的思路：
//https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/